using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Text;
using System.Reflection;
using UnityEditor.Callbacks;

namespace TCC.Framework
{
    /// <summary>
    /// 数据编辑器
    /// </summary>
    public class DataEditor : EditorWindow
    {
        public static string tableInfoPath = "Assets/TCCFramework/Editor/TableTool/TableInfo.asset";
        public static string tableIconPath = "Assets/TCCFramework/Editor/Textures/tableIcon.png";
        
        [SerializeField]public static TableInfo tableInfo;

        public static TableInfo _TableInfo
        {
            get
            {
                tableInfo = AssetDatabase.LoadAssetAtPath<TableInfo>(tableInfoPath);
                return tableInfo;
            }
            set
            {
                tableInfo = value;
            }
        }
        private static bool _isOpen;

        public static bool IsOpen
        {
            get => _isOpen; set
            {
                _isOpen = value;
                if (!_isOpen)
                {
                    AddFieldWin.IsOpen = false;
                    NewDataTableWin.IsOpen = false;
                }
            }
        }

        public MethodInfo methodInfo;

        object tableViewObj;

        static int searchFiledIndex;
        static string[] fields;
        [SerializeField]public static DataEditor win;
        
        public static void OpenWin(DataTable data)
        {
            win = GetWindow<DataEditor>();
            win.titleContent.text = "数据编辑器";
            win.minSize = new Vector2(800, 600);
            win.maxSize = new Vector2(Screen.currentResolution.width, Screen.currentResolution.height);
            InitDataInfo(data);
            win.Show();
            IsOpen = true;
        }

        public static void InitDataInfo(DataTable data)
        {
            if (data == null) return;
            _TableInfo.dataTable = data;
            _TableInfo._EntityPath="";
            UnityEngine.Object obj;
            foreach (var item in AssetDatabase.GetDependencies(AssetPathTool.GetAssetRelativePath(data), false))
            {
                obj = AssetDatabase.LoadMainAssetAtPath(AssetPathTool.AbsPathToRelativePath(item));
                if (obj is MonoScript&&obj.name== data.GetType().Name)
                {
                    _TableInfo._EntityPath = item;
                    break;
                }
            }
            string path = AssetDatabase.GetAssetPath(data);
            path = path.Remove(path.LastIndexOf('/'));
            SetTableInfoField(path);
        }

        public TableView<T> Init<T>() where T : class, new()
        {
            List<TableColumn<T>> _tableColumns = new List<TableColumn<T>>();
            foreach (var field in _TableInfo._fields)
            {
                string Lable = string.IsNullOrEmpty(field._nickName) ? field._fieldName : field._nickName;
                switch (field._fieldType)
                {
                    case FieldType.String:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            Compare = (a, b) =>
                            {
                                return ((string)a.GetType().GetField(field._fieldName).GetValue(a)).CompareTo((string)b.GetType().GetField(field._fieldName).GetValue(b));
                            },
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.TextField(cellRect, (string)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.Single:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            Compare = (a, b) =>
                            {
                                return ((float)a.GetType().GetField(field._fieldName).GetValue(a)).CompareTo((float)b.GetType().GetField(field._fieldName).GetValue(b));
                            },
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.FloatField(cellRect, (float)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.Int32:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            Compare = (a, b) =>
                            {
                                return ((int)a.GetType().GetField(field._fieldName).GetValue(a)).CompareTo((int)b.GetType().GetField(field._fieldName).GetValue(b));
                            },
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.IntField(cellRect, (int)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.Boolean:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            Compare = (a, b) =>
                            {
                                return ((bool)a.GetType().GetField(field._fieldName).GetValue(a)).CompareTo((bool)b.GetType().GetField(field._fieldName).GetValue(b));
                            },
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.Toggle(cellRect, (bool)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.Color:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.ColorField(cellRect, (Color)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.Enum:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            Compare = (a, b) =>
                            {
                                return ((Enum)a.GetType().GetField(field._fieldName).GetValue(a)).CompareTo((Enum)b.GetType().GetField(field._fieldName).GetValue(b));
                            },
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.EnumPopup(cellRect, (Enum)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.GameObject:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, (GameObject)EditorGUI.ObjectField(cellRect, (GameObject)info.GetValue(data), typeof(GameObject), true));
                            },
                        });
                        break;
                    case FieldType.Texture:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, (Texture)EditorGUI.ObjectField(cellRect, (Texture)info.GetValue(data), typeof(Texture), true));
                            },
                        });
                        break;
                    case FieldType.Vector2:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.Vector2Field(cellRect, "", (Vector2)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.Vector3:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data, EditorGUI.Vector3Field(cellRect, "", (Vector3)info.GetValue(data)));
                            },
                        });
                        break;
                    case FieldType.Object:
                        _tableColumns.Add(new TableColumn<T>()
                        {
                            headerContent = new GUIContent(Lable),
                            width = 100,
                            canSort = true,
                            autoResize = false,
                            DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                            {
                                FieldInfo info = data.GetType().GetField(field._fieldName);
                                info.SetValue(data,EditorGUI.ObjectField(cellRect, (UnityEngine.Object)info.GetValue(data), typeof(UnityEngine.Object), true));
                            },
                        });
                        break;
                }
            }
            FieldInfo property = _TableInfo.dataTable.GetType().GetField("datas");
            object obj = property.GetValue(_TableInfo.dataTable);
            TableView<T> _tableView = new TableView<T>(obj as List<T>, _tableColumns);
            _tableView.IsEnableSearch = true;
            _tableView.OnSearch = OnSearch;
            _tableView.DrawSearch = DrawSearch;
            return _tableView;
        }

        /// <summary>
        /// 绘制搜索框
        /// </summary>
        /// <param name="arg0"></param>
        /// <returns></returns>
        private Rect DrawSearch(Rect arg0)
        {
            Rect sub = new Rect(arg0.x, arg0.y, 60, 16);
            EditorGUI.LabelField(sub, "检索字段: ");
            sub.Set(arg0.x + 60, arg0.y, 60, 16);
            searchFiledIndex = EditorGUI.Popup(sub, searchFiledIndex, fields);
            sub.Set(arg0.x + 120, arg0.y, arg0.width - 122, 18);
            return sub;
        }

        private bool OnSearch(object arg0, string arg1)
        {
            string filedName = "";
            foreach (var item in _TableInfo._fields)
            {
                if (item._nickName == _TableInfo._fields[searchFiledIndex]._nickName)
                    filedName = _TableInfo._fields[searchFiledIndex]._fieldName;
            }
            return arg0.GetType().GetField(filedName).GetValue(arg0).ToString().Contains(arg1);
        }

        public virtual void OnGUI()
        {
            if (tableInfo != null&&tableInfo.dataTable!=null)
                GUI.Label(new Rect(Screen.width / 2 - 100, -8, Screen.width - 180, 30), AssetDatabase.GetAssetPath(tableInfo.dataTable));
            EditorGUILayout.BeginHorizontal();
            if (GUI.Button(new Rect(0, 0, 50, 20), "新建", EditorStyles.toolbarButton))
            {
                NewDataTableWin.ShowWin();
            }
            OpenFiel();
            if (GUI.Button(new Rect(100, 0, 50, 20), "保存", EditorStyles.toolbarButton))
            {
                EditorUtility.SetDirty(_TableInfo.dataTable);
                AssetDatabase.SaveAssets();
            }

            EditorField();

            CreatJson();

            EditorGUILayout.EndHorizontal();

            DrawView();
        }

        public virtual void CreatJson()
        {
            if (GUI.Button(new Rect(Screen.width - 90, 0, 90, 20), "生成Json文件", EditorStyles.toolbarButton))
            {
                if (tableInfo != null & tableInfo.dataTable != null)
                {
                    string path = tableInfo._savePath + "/" + tableInfo._fileName + ".json";
                    FileOperations.WriteJsonData(tableInfo.dataTable, path);
                    AssetDatabase.Refresh();
                }
                else
                {
                    Debug.Log("创建Json文件失败！");
                }
            }
        }

        public virtual void OpenFiel()
        {
            if (GUI.Button(new Rect(50, 0, 50, 20), "打开", EditorStyles.toolbarButton))
            {
                string path = EditorUtility.OpenFilePanel("选择数据", "Assets", "asset");
                if (string.IsNullOrEmpty(path)) return;
                string fullPath = path.Replace("\\", "/");
                fullPath = fullPath.Remove(fullPath.LastIndexOf('/'));
                path = "Assets" + path.Replace(Application.dataPath, "");
                _TableInfo.dataTable = AssetDatabase.LoadAssetAtPath<DataTable>(path);

                if (_TableInfo.dataTable)
                {
                    SetTableInfoField(fullPath);
                    methodInfo = null;
                    tableViewObj = null;
                }
            }
        }

        public virtual void EditorField()
        {
            if (_TableInfo._fields != null && _TableInfo._fields.Count > 0)
            {
                if (GUI.Button(new Rect(150, 0, 60, 20), "编辑字段", EditorStyles.toolbarButton))
                {
                    AddFieldWin.ShowWin(_TableInfo._fields);
                }
            }
        }

        public virtual void DrawView()
        {
            if (_TableInfo.dataTable != null)
            {
                if (_TableInfo._fields.Count <= 0)
                {
                    string path = AssetDatabase.GetAssetPath(_TableInfo.dataTable);
                    path = path.Replace("\\", "/");
                    path = path.Remove(path.LastIndexOf('/'));
                    SetTableInfoField(path);
                }
                if (methodInfo == null)
                {
                    MethodInfo member = typeof(DataEditor).GetMethod("Init");
                    if (member != null)
                        methodInfo = member.MakeGenericMethod(new Type[] { _TableInfo.dataTable.GetType().GetNestedType("Data") });
                }
                else
                {
                    if (tableViewObj == null)
                        tableViewObj = methodInfo.Invoke(this, null);
                    tableViewObj.GetType().GetMethod("OnGUI").Invoke(tableViewObj, new object[] { new Rect(0, 25, position.width, position.height - 25) });
                }
            }

        }
        static void SetTableInfoField(string path)
        {
            _TableInfo._fileName = _TableInfo.dataTable.GetType().Name;
            _TableInfo._savePath = path;
            _TableInfo._fields.Clear();
            foreach (var field in _TableInfo.dataTable.GetType().GetNestedTypes()[0].GetFields())
            {
                string nickNmae = "";
                foreach (var item in field.GetCustomAttributes())
                {
                    if (item is TableHeaderAttribute)
                        nickNmae = (item as TableHeaderAttribute).Name;
                }
                string enumName = "";
                List<Field.EnumFiled> enumFileds = new List<Field.EnumFiled>();
                FieldType type = (FieldType)Enum.Parse(typeof(FieldType), field.FieldType.IsEnum ? "Enum" : field.FieldType.Name);
                if (type == FieldType.Enum)
                {
                    enumName = field.FieldType.Name;
                    foreach (var item in Enum.GetNames(field.FieldType))
                    {
                        enumFileds.Add(new Field.EnumFiled { enumFiled = item });
                    }
                }
                _TableInfo._fields.Add(new Field
                {
                    _fieldName = field.Name,
                    _nickName = nickNmae,
                    _fieldType = type,
                    enumName = enumName,
                    enumFiled = enumFileds
                });
            }

            fields = new string[_TableInfo._fields.Count];
            for (int i = 0; i < _TableInfo._fields.Count; i++)
            {
                if (_TableInfo._fields[i]._fieldType == FieldType.Int32 ||
                   _TableInfo._fields[i]._fieldType == FieldType.Single ||
                   _TableInfo._fields[i]._fieldType == FieldType.String)
                    fields[i] = _TableInfo._fields[i]._nickName;
            }
        }

        private void OnDestroy()
        {
            IsOpen = false;
            EditorUtility.SetDirty(_TableInfo.dataTable);
            AssetDatabase.SaveAssets();
        }
    }

    public class AddFieldWin : EditorWindow
    {
        private static List<TableColumn<Field>> _tableColumns;
        private static TableView<Field> _tableView;
        public static AddFieldWin win;
        private static bool _isOpen = false;

        public static bool IsOpen
        {
            get => _isOpen;
            set
            {
                if (_isOpen != value)
                {
                    _isOpen = value;
                    if (!_isOpen)
                    {
                        win.Close();
                        AddEnumValue.IsOpen = false;
                    }
                }
            }
        }
        public static void ShowWin(List<Field> fields)
        {
            win = GetWindow<AddFieldWin>();
            win.titleContent.text = "编辑字段";
            win.minSize = new Vector2(400, 600);
            Init();
            win.Show();
            IsOpen = true;
        }

        protected static void Init()
        {
            _tableColumns = new List<TableColumn<Field>>();
            _tableColumns.Add(new TableColumn<Field>()
            {
                headerContent = new GUIContent("字段"),
                width = 100,
                canSort = true,
                autoResize = false,
                Compare = (a, b) =>
                {
                    return a._fieldName.CompareTo(b._fieldName);
                },
                DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                {
                    data._fieldName = EditorGUI.TextField(cellRect, data._fieldName);
                },
            });
            _tableColumns.Add(new TableColumn<Field>()
            {
                headerContent = new GUIContent("字段别称"),
                width = 100,
                canSort = true,
                autoResize = false,
                Compare = (a, b) =>
                {
                    return a._nickName.CompareTo(b._nickName);
                },
                DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                {
                    data._nickName = EditorGUI.TextField(cellRect, data._nickName);
                },
            });
            _tableColumns.Add(new TableColumn<Field>()
            {
                headerContent = new GUIContent("类型"),
                width = 100,
                canSort = true,
                autoResize = false,
                Compare = (a, b) =>
                {
                    return a._fieldType.CompareTo(b._fieldType);
                },
                DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                {
                    data._fieldType = (FieldType)EditorGUI.EnumPopup(cellRect, data._fieldType);
                    if (data._fieldType == FieldType.Enum)
                    {
                        if (GUI.Button(new Rect(cellRect.x + cellRect.width, cellRect.y, cellRect.width, cellRect.height), "设置枚举"))
                        {
                            AddEnumValue.ShowWin(DataEditor._TableInfo._fields.IndexOf(data));
                        }
                    }
                },
            });
            _tableView = new TableView<Field>(DataEditor._TableInfo._fields, _tableColumns);
        }

        void OnGUI()
        {
            if (_tableView == null)
                Init();
            _tableView.OnGUI(new Rect(0, 0, position.width, position.height - 30));
            if (GUI.Button(new Rect(0, position.height - 30, position.width, 20), "确认"))
            {
                WriteFlied();
                AssetDatabase.Refresh();
                CompilingFinishedCallback.Set<AddFieldWin>("CreateDataPrefab");
                IsOpen = false;
            }
        }

        static void CreateDataPrefab()
        {
            if (!Directory.Exists(DataEditor._TableInfo._savePath))
                Directory.CreateDirectory(DataEditor._TableInfo._savePath);
            string path = DataEditor._TableInfo._savePath + "/" + DataEditor._TableInfo._fileName + ".asset";
            if (path.Contains(Application.dataPath))
                path = "Assets" + path.Replace(Application.dataPath, "");
            Type type = Assembly.Load("Assembly-CSharp").GetType("TCC.Framework." + DataEditor._TableInfo._fileName);
            if (DataEditor._TableInfo.dataTable != null && DataEditor._TableInfo.dataTable.GetType() == type) return;
            ScriptableObject obj = CreateInstance(type);

            if (obj != null)
            {
                Texture texture = AssetDatabase.LoadAssetAtPath<Texture>(DataEditor.tableIconPath);
                SetIcon(obj, texture);
                AssetDatabase.CreateAsset(obj, path);
                AssetDatabase.Refresh();
                DataEditor._TableInfo.dataTable = obj as DataTable;
            }
        }

        public virtual void WriteFlied()
        {
            string path = AssetPathTool.RelativePathToAbsPath(DataEditor._TableInfo._EntityPath);
            if(string.IsNullOrEmpty(path))
               path = AssetPathTool.RelativePathToAbsPath(EditorConfigFile.mainTablePath+ DataEditor._TableInfo._fileName+".cs");
            string floderPath = path.Remove(path.LastIndexOf('/'));
            if (!Directory.Exists(floderPath))
                Directory.CreateDirectory(floderPath);
            if(!File.Exists(path))
            {
                using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
                {
                    StringBuilder st = new StringBuilder();
                    st.Append("using TCC.Framework;\nusing System.Collections.Generic;\nusing UnityEngine;\n using System;\n");
                    st.Append($"namespace TCC.Framework\n");
                    st.Append("{\n");
                    st.Append($"\n\tpublic class {DataEditor._TableInfo._fileName}:DataTable\n");
                    st.Append("\t{\n");
                    st.Append(GetFlieText());
                    st.Append("\t\n}\n");
                    st.Append("\n}");
                    StreamWriter writer = new StreamWriter(fs);
                    writer.WriteLine(st);
                    writer.Flush();
                    writer.Dispose();
                    writer.Close();
                }
            }
            else
            {
                string textAsset = File.ReadAllText(path);
                int index = textAsset.IndexOf("class " + DataEditor._TableInfo._fileName);
                if (index > 0)
                {
                    int pos = textAsset.IndexOf('{', index);
                    int f_bracket = 0;
                    int f = 0;
                    int h = 0;
                    for (int i = index; i < textAsset.Length; i++)
                    {
                        if (textAsset[i] == '{')
                            f++;
                        else if (textAsset[i] == '}')
                            h++;
                        if (f != 0 && h != 0 && f == h)
                        {
                            f_bracket = i;
                            break;
                        }
                    }
                    textAsset = textAsset.Remove(pos + 1, (f_bracket - pos) - 1);
                    string str = GetFlieText();
                    textAsset = textAsset.Insert(pos + 1, str.ToString());
                    File.WriteAllText(path, textAsset);
                }
            }
        }

        private static string GetFlieText()
        {
            List<StringBuilder> enumStr = new List<StringBuilder>();
            StringBuilder str = new StringBuilder();
            str.Append($"\n\t\tpublic List<Data> datas = new List<Data>();\n");
            str.Append("\n\t\t[Serializable]\n\t\tpublic class Data\n\t\t{\n");
            foreach (var item in DataEditor._TableInfo._fields)
            {
                switch (item._fieldType)
                {
                    case FieldType.Int32:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public int {item._fieldName};\n");
                        break;
                    case FieldType.String:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public string {item._fieldName};\n");
                        break;
                    case FieldType.Single:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public float {item._fieldName};\n");
                        break;
                    case FieldType.Enum:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public {item.enumName} {item._fieldName};\n");
                        StringBuilder enumSt = new StringBuilder();
                        enumSt.Append($"\t\t\tpublic enum {item.enumName}\n");
                        enumSt.Append("\t\t\t{\n");
                        foreach (var enumFlied in item.enumFiled)
                            enumSt.Append($"\t\t\t\t{enumFlied.enumFiled},\n");
                        enumSt.Append("\t\t\t}\n");
                        enumStr.Add(enumSt);
                        break;
                    case FieldType.GameObject:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public GameObject {item._fieldName};\n");
                        break;
                    case FieldType.Boolean:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public bool {item._fieldName};\n");
                        break;
                    case FieldType.Color:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public Color {item._fieldName};\n");
                        break;
                    case FieldType.Texture:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public Texture {item._fieldName};\n");
                        break;
                    case FieldType.Vector2:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public Vector2 {item._fieldName};\n");
                        break;
                    case FieldType.Vector3:
                        str.Append($"\t\t\t/// <summary>\n\t\t\t///{item._nickName}\n\t\t\t/// </summary>\n\t\t\t[TableHeader(\"{item._nickName}\")]public Vector3 {item._fieldName};\n");
                        break;
                }
            }
            if (enumStr.Count > 0)
                foreach (var item in enumStr)
                    str.Append(item.ToString());
            str.Append("\t\t}\n\t");
            return str.ToString();
        }

        static void SetIcon(UnityEngine.Object gObj, Texture texture)
        {
            Type ty = typeof(EditorGUIUtility);
            //EditorGUIUtility.SetIconForObject(gObj, texture as Texture2D);
            MethodInfo mi = ty.GetMethod("SetIconForObject", BindingFlags.NonPublic | BindingFlags.Static);
            mi.Invoke(null, new object[] { gObj, texture });
        }
    }

    public class NewDataTableWin : EditorWindow
    {
        public static NewDataTableWin win;
        private static bool _isOpen = false;
        private string _fileName = "NewData";
        public static bool IsOpen
        {
            get => _isOpen;
            set
            {
                if (_isOpen != value)
                {
                    _isOpen = value;
                    if (!_isOpen)
                        win.Close();
                }
            }
        }
        public static void ShowWin()
        {
            win = GetWindow<NewDataTableWin>();
            win.titleContent.text = "新建数据";
            win.maxSize = new Vector2(400, 100);
            IsOpen = true;
            win.Show();
        }

        void OnGUI()
        {
            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal("Box");
            GUILayout.Label("数据表名：", GUILayout.Width(60));
            _fileName = EditorGUILayout.TextField(_fileName);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal("Box");
            GUILayout.Label("存储路径：", GUILayout.Width(60));
            DataEditor._TableInfo._savePath = EditorGUILayout.TextField(DataEditor._TableInfo._savePath);
            GUIContent content = EditorGUIUtility.IconContent("Folder Icon");
            content.text = "浏览";
            if (GUILayout.Button(content, GUILayout.Width(50), GUILayout.Height(20)))
            {
                DataEditor._TableInfo._savePath = EditorUtility.OpenFolderPanel("选择存储路径", "Assets", "");
            }
            EditorGUILayout.EndHorizontal();
            if (GUILayout.Button("创建", "LargeButton"))
            {
                DataEditor._TableInfo.dataTable = null;
                DataEditor._TableInfo._fields.Clear();
                DataEditor._TableInfo._fileName = _fileName;
                CreateFile();
                AddFieldWin.ShowWin(DataEditor._TableInfo._fields);
                IsOpen = false;
            }
            EditorGUILayout.EndVertical();
        }

        void CreateFile()
        {
            string path = AssetPathTool.RelativePathToAbsPath(EditorConfigFile.mainTablePath+ DataEditor._TableInfo._fileName+".cs");
           
            if(File.Exists(path))
            {
                Debug.LogError("已存在同名表文件！");
            }
            else
            {
                using(FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
                {
                    StringBuilder st = new StringBuilder();
                    st.Append("using System.Collections.Generic;\nusing UnityEngine;\n using System;\n");
                    st.Append($"namespace TCC.Framework\n");
                    st.Append("{\n");
                    st.Append($"\n\tpublic class {DataEditor._TableInfo._fileName}:DataTable\n");
                    st.Append("\t{\n");
                    st.Append("\t\n}\n");
                    st.Append("\n}");
                    StreamWriter writer = new StreamWriter(fs);
                    writer.WriteLine(st);
                    writer.Flush();
                    writer.Dispose();
                    writer.Close();
                }
            }
        }
    }

    public class AddEnumValue : EditorWindow
    {
        int _index;
        private static bool _isOpen = false;
        static AddEnumValue win;

        private static List<TableColumn<Field.EnumFiled>> _tableColumns;
        private static TableView<Field.EnumFiled> _tableView;
        public static bool IsOpen
        {
            get => _isOpen;
            set
            {
                if (_isOpen != value)
                {
                    _isOpen = value;
                    if (!_isOpen)
                        win.Close();
                }
            }
        }
        public static void ShowWin(int index)
        {
            win = GetWindow<AddEnumValue>();
            win.titleContent.text = "设置枚举";
            win.minSize = new Vector2(400, 400);
            win._index = index;
            Init();
            win.Show();
            IsOpen = true;
        }

        static void Init()
        {
            _tableColumns = new List<TableColumn<Field.EnumFiled>>();
            _tableColumns.Add(new TableColumn<Field.EnumFiled>()
            {
                headerContent = new GUIContent("枚举值"),
                width = 100,
                canSort = true,
                autoResize = false,
                Compare = (a, b) =>
                {
                    return a.enumFiled.CompareTo(b.enumFiled);
                },
                DrawCell = (cellRect, data, rowIndex, isSelected, isFocused) =>
                {
                    data.enumFiled = EditorGUI.TextField(cellRect, data.enumFiled);
                },
            });
            _tableView = new TableView<Field.EnumFiled>(DataEditor._TableInfo._fields[win._index].enumFiled, _tableColumns);
        }

        void OnGUI()
        {
            EditorGUILayout.BeginHorizontal("Box");
            GUILayout.Label("枚举名：", GUILayout.Width(55));
            DataEditor._TableInfo._fields[_index].enumName = EditorGUILayout.TextField(DataEditor._TableInfo._fields[_index].enumName);
            EditorGUILayout.EndHorizontal();
            _tableView.OnGUI(new Rect(0, 30, position.width, position.height - 50));
            if (GUI.Button(new Rect(0, position.height - 30, position.width, 20), "确认"))
            {
                IsOpen = false;
            }
        }
    }

    [SerializeField]
    public class Field
    {
        public string _fieldName;
        public string _nickName;
        public FieldType _fieldType;
        public string enumName;
        public List<EnumFiled> enumFiled = new List<EnumFiled> { new EnumFiled("NONE") };

        [SerializeField]
        public class EnumFiled
        {
            public string enumFiled;

            public EnumFiled()
            {
            }
            public EnumFiled(string filed)
            {
                enumFiled = filed;
            }
        }
    }

    public enum FieldType
    {
        Int32,
        String,
        Single,
        Boolean,
        Vector2,
        Vector3,
        Color,
        Enum,
        GameObject,
        Texture,
        Object
    }

    [CustomEditor(typeof(DataTable), true)]
    public sealed class SetDataTableInspector : Editor
    {
        [OnOpenAsset]
        public static bool OnOpenTable(int instanceID, int line)
        {
            DataTable data = EditorUtility.InstanceIDToObject(instanceID) as DataTable;
            if (data != null)
            {
                if (data is LanguageDate)
                {
                    LanguageTable.OpenWin(data);
                    return true;
                }
                DataEditor.OpenWin(data);
                return true;
            }
            return false;
        }
        public override void OnInspectorGUI()
        {
            //base.OnInspectorGUI();
        }
    }
}

